package com.itheima.leetcode.od.b.string;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * (C卷,100分)- 密码解密（Java & JS & Python & C）
 * <p>
 * 题目描述
 * <p>
 * 给定一段“密文”字符串 s，其中字符都是经过“密码本”映射的，现需要将“密文”解密并输出。
 * <p>
 * 映射的规则（'a' ~ 'i'）分别用（'1' ~ '9'）表示；（'j' ~ 'z'）分别用（"10*" ~ "26*"）表示。
 * <p>
 * 约束：映射始终唯一。
 * <p>
 * 输入描述
 * <p>
 * “密文”字符串
 * <p>
 * 输出描述
 * <p>
 * 明文字符串
 * <p>
 * 备注
 * 翻译后的文本长度在100以内
 * <p>
 * 用例
 * <p>
 * 输入	20*19*20*
 * 输出	tst
 * 说明	无
 * <p>
 * 题目解析
 * <p>
 * 本题有多种解题思路，我的思路是利用字符串替换操作。
 * <p>
 * 即将如下密文和明文进行按照顺序依次映射替换
 * <p>
 * "26*" → "z"
 * "25*" → "y"
 * ...
 * "10*" → "j"
 * "9" → "i"
 * ...
 * "1" → "a"
 * 这里优先将从“26*” ~ "10*" 开始映射替换，比如题目用例：
 * <p>
 * 20*19*20*
 * <p>
 * 如果优先进行 "1" ~ “9” 密文的映射替换，则会产生错误答案。
 * <p>
 * 更多实现细节，请看代码。
 */
public class CipherDecryptor {

    public static void main(String[] args) {
        // 获取输入的加密文本
        String encryptedText = "20*19*20*";

        // 执行解密并输出结果
        System.out.println(getResult(encryptedText));
    }

    /**
     * 解密密文字符串的主要方法
     * <p>
     * 核心策略：优先级替换法
     * - 长模式优先：防止短模式干扰长模式的识别
     * - 从大到小遍历：确保26*到1的顺序处理
     *
     * @param encryptedText
     * @return
     */
    public static String getResult(String encryptedText) {
        // 构建解密字典：使用LinkedHashMap保持插入顺序
        // 这样可以确保长模式（如26*）先于短模式（如2,6）被处理
        Map<String, Character> decryptDict = new LinkedHashMap<>();

        // 逆向构建映射表：从z到a对应26到1
        for (int num = 26; num >= 1; num--) {
            String cipherKey;

            if (num >= 10) {
                // 双位数加星号格式：10*对应j，11*对应k，...，26*对应z
                cipherKey = num + "*";
            } else {
                // 单位数格式：1对应a，2对应b，...，9对应i
                cipherKey = String.valueOf(num);
            }

            // 计算对应的明文字母
            // num=1对应'a'，num=2对应'b'，以此类推
            char plainChar = (char) ('a' + num - 1);
            decryptDict.put(cipherKey, plainChar);
        }

        // 执行批量替换：按照字典的插入顺序进行替换
        String decryptedResult = encryptedText;
        for (Map.Entry<String, Character> entry : decryptDict.entrySet()) {
            String cipherPattern = entry.getKey();
            char plainLetter = entry.getValue();

            // 将密文中的所有匹配模式替换为对应的明文字母
            decryptedResult = decryptedResult.replace(cipherPattern, String.valueOf(plainLetter));
        }

        return decryptedResult;
    }
}